package io.polly.thread.monitor;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.NamedThreadFactory;
import io.polly.common.config.DynamicExecutorProperties;
import io.polly.common.event.CollectEvent;
import io.polly.thread.DynamicExecutor;
import io.polly.thread.DynamicExecutorRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.event.ApplicationEventMulticaster;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static io.polly.thread.monitor.AlarmManager.doAlarm;

/**
 * @author ldz
 * @version V1.0
 * @title: DynamicExecutorMonitor
 * @description: TODO(用一句话描述该文件做什么)
 * @date: 2022/3/21 19:58
 */
@Slf4j
public class DynamicExecutorMonitor implements ApplicationRunner {

    @Resource
    private static DynamicExecutorProperties dynamicExecutorProperties;

    @Resource
    private ApplicationEventMulticaster applicationEventMulticaster;

    private static final ScheduledExecutorService MONITOR_EXECUTOR = new ScheduledThreadPoolExecutor(
            1,
            new NamedThreadFactory("dynamicExecutor-monitor", true));



    @Override
    public void run(ApplicationArguments args) throws Exception {

        MONITOR_EXECUTOR.scheduleWithFixedDelay(this::run,
                0, dynamicExecutorProperties.getMonitorInterval(), TimeUnit.SECONDS);

    }

    private void run() {
        List<String> names = DynamicExecutorRegistry.listRegisterExecutorName();
        if (CollUtil.isEmpty(names)) {
            return;
        }
        names.forEach(name -> {
            DynamicExecutor executor = DynamicExecutorRegistry.getExecutor(name);
            AlarmManager.triggerAlarm(() -> doAlarm(executor));
        });

        publishEvent();
    }



    private void publishEvent() {
        CollectEvent event = new CollectEvent(this, dynamicExecutorProperties);
        applicationEventMulticaster.multicastEvent(event);
    }
}
